/**
  ******************************************************************************
  * @file    bsp_eth.c
  * @author  Iron
  * @date    2022-01-01
  * @version v1.0
  * @brief   bsp_eth c file
  */

/* Private includes ----------------------------------------------------------*/
#include "bsp_eth.h"

/* Private define ------------------------------------------------------------*/

/* Priority of Interrupt */
#define BSP_UART_ETH_PRI        1u

/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/


/*----------------------------------------------------------------------------*/
__WEAK void bsp_eth_link_status_irq_handle(uint8_t link_status)
{

}

__WEAK void bsp_eth_recv_irq_handle(uint16_t rxlen)
{

}

__WEAK void bsp_eth_recv_error_irq_handle(void)
{

}

__WEAK void bsp_eth_send_irq_handle(void)
{

}

__WEAK void bsp_eth_send_error_irq_handle(uint16_t txaddr, uint16_t txlen)
{

}

/*----------------------------------------------------------------------------*/
void bsp_eth_get_mac(uint8_t *mac_addr)
{
    int32_t i;
    uint8_t transbuf[ETH_MAC_ADDR_LEN];

    GetMACAddress(transbuf);

    for (i = 0; i < ETH_MAC_ADDR_LEN; i++)
    {
        mac_addr[ETH_MAC_ADDR_LEN - 1 - i] = transbuf[i];
    }
}

/*----------------------------------------------------------------------------*/
uint16_t bsp_eth_phy_reg_read(uint16_t phy_reg)
{
    uint8_t reg_op;

    reg_op = phy_reg & RB_ETH_MIREGADR_MIRDL;

    R8_ETH_MIREGADR = RB_ETH_MIREGADR_MIIWR | reg_op;

    return R16_ETH_MIRD;
}

void bsp_eth_phy_reg_write(uint16_t phy_reg, uint16_t reg_value)
{
    uint8_t reg_op;

    R16_ETH_MIWR = reg_value;

    reg_op = (phy_reg & RB_ETH_MIREGADR_MIRDL);

    R8_ETH_MIREGADR = reg_op;
}

/* 以太网中断中断服务函数 */
void ETH_IRQHandler(void)
{
    UINT8V eth_irq_flag = R8_ETH_EIR;

    BSP_ETH_LED_YELLOW_TOGGLE();

    /* Link 变化标志 */
    if (eth_irq_flag & RB_ETH_EIR_LINKIF)
    {
        uint8_t link_status;
        uint16_t reg_value;

        reg_value = bsp_eth_phy_reg_read(PHY_BMSR); // 读取PHY状态寄存器

        link_status = (reg_value & PHY_BMSR_LINKED_STATUS) ? true : false;

        bsp_eth_link_status_irq_handle(link_status);

        R8_ETH_EIR = RB_ETH_EIR_LINKIF; // 清除标志
    }

    /* 接收完成标志 */
    if (eth_irq_flag & RB_ETH_EIR_RXIF)
    {
        R8_ETH_ECON1 &= ~RB_ETH_ECON1_RXEN; // 接收禁止

        bsp_eth_recv_irq_handle(R16_ETH_ERXLN);

        R8_ETH_EIR = RB_ETH_EIR_RXIF; // 清除标志
    }

    /* 发送完成标志 */
    if (eth_irq_flag & RB_ETH_EIR_TXIF)
    {
        bsp_eth_send_irq_handle();

        R8_ETH_EIR = RB_ETH_EIR_TXIF; // 清除标志
    }

    /* 发送错误标志 */
    if (eth_irq_flag & RB_ETH_EIR_TXERIF)
    {
        uint16_t txaddr = R16_ETH_ETXST;
        uint16_t txlen = R16_ETH_ETXLN;

        bsp_eth_send_error_irq_handle(txaddr, txlen);

        R8_ETH_EIR = RB_ETH_EIR_TXERIF; // 清除标志
    }

    /* 接收错误标志 */
    if (eth_irq_flag & RB_ETH_EIR_RXERIF)
    {
        bsp_eth_recv_error_irq_handle();

        R8_ETH_EIR = RB_ETH_EIR_RXERIF; // 清除标志
    }
}

/*----------------------------------------------------------------------------*/
int32_t bsp_eth_get_rx_status(void)
{
    if (R8_ETH_ECON1 & RB_ETH_ECON1_RXEN)
    {
        return BSP_ETH_ENABLE;
    }

    return BSP_ETH_DISABLE;
}

// rxbuf 必须 4 字节对齐
int32_t bsp_eth_rx_enable(uint32_t rxbuf, uint16_t rxbuf_size)
{
    if (R8_ETH_ESTAT & RB_ETH_ESTAT_RXBUSY)
    {
        return BSP_ETH_RX_BUSY;
    }

    R16_ETH_ERXST = rxbuf;
    R16_ETH_MAMXFL = rxbuf_size;   // MAC_MAX_LEN 1536

    R8_ETH_ECON1 |= RB_ETH_ECON1_RXEN; // 接收使能控制

    return BSP_ETH_SUCCESS;
}

/*----------------------------------------------------------------------------*/
int32_t bsp_eth_get_tx_status(void)
{
    if (R8_ETH_ECON1 & RB_ETH_ECON1_TXRTS)
    {
        return BSP_ETH_ENABLE;
    }

    return BSP_ETH_DISABLE;
}

// txbuf 必须 4 字节对齐
int32_t bsp_eth_tx_enable(uint32_t txbuf, size_t txbuf_size)
{
    if (R8_ETH_ECON1 & RB_ETH_ECON1_TXRTS)
    {
        return BSP_ETH_TX_BUSY;
    }

    R16_ETH_ETXLN = txbuf_size;
    R16_ETH_ETXST = txbuf;

    R8_ETH_ECON1 |= RB_ETH_ECON1_TXRTS;  // 发送开始，发送完成后自动清零

    return BSP_ETH_SUCCESS;
}

/*----------------------------------------------------------------------------*/
static void ch57x_eth_init(uint8_t *mac_addr, uint16_t max_length)
{
    // 清除所有中断
    R8_ETH_EIE = 0;

    //开启中断
    R8_ETH_EIE |= RB_ETH_EIE_INTIE | RB_ETH_EIE_RXIE | RB_ETH_EIE_LINKIE | RB_ETH_EIE_TXIE | RB_ETH_EIE_TXERIE | RB_ETH_EIE_RXERIE;

    //开启50欧上拉
    R8_ETH_EIE |= RB_ETH_EIE_R_EN50;

    //清除中断标志
    R8_ETH_EIR = 0xff;

    //清除状态
    R8_ETH_ESTAT |= RB_ETH_ESTAT_INT | RB_ETH_ESTAT_BUFER;

    // PHY 模拟参数设置
    R8_ETH_ECON2 &= ~0x0F;
    R8_ETH_ECON2 |= (2 << 1);

    //收发模块复位
    R8_ETH_ECON1 |= (RB_ETH_ECON1_TXRST | RB_ETH_ECON1_RXRST);
    R8_ETH_ECON1 &= ~(RB_ETH_ECON1_TXRST | RB_ETH_ECON1_RXRST);

    //过滤模式，接收包类型
    R8_ETH_ERXFCON = 0;

    //过滤模式，限制包类型
    R8_ETH_MACON1 |= RB_ETH_MACON1_MARXEN;      //MAC接收使能
    R8_ETH_MACON2 &= ~RB_ETH_MACON2_PADCFG;
    R8_ETH_MACON2 |= PADCFG_AUTO_3;             //所有短包自动填充到 60
    R8_ETH_MACON2 |= RB_ETH_MACON2_TXCRCEN;     //硬件填充CRC
    R8_ETH_MACON2 &= ~RB_ETH_MACON2_HFRMEN;     //不接收巨型帧
    R8_ETH_MACON2 |= RB_ETH_MACON2_FULDPX;      //全双工

    // 最大接收包长度寄存器
//    R16_ETH_MAMXFL = ETH_MAX_PACKET_SIZE;   // MAC_MAX_LEN 1536

    // 设置 MAC 地址
    R8_ETH_MAADRL6 = mac_addr[0]; // 0x84
    R8_ETH_MAADRL5 = mac_addr[1]; // 0xc2
    R8_ETH_MAADRL4 = mac_addr[2]; // 0xe4
    R8_ETH_MAADRL3 = mac_addr[3]; // 0x01
    R8_ETH_MAADRL2 = mac_addr[4]; // 0x02
    R8_ETH_MAADRL1 = mac_addr[5]; // 0x03
}

/*----------------------------------------------------------------------------*/
int32_t bsp_eth_init(uint8_t *mac_addr)
{
    // 打开以太网络的时钟和电源
    PWR_PeriphClkCfg(ENABLE, RB_SLP_CLK_ETH);   // 打开 ETH 时钟
    PWR_UnitModCfg(ENABLE, UNIT_ETH_PHY);       // 打开 ETH 和 PHY 电源
    GPIOAGPPCfg(ENABLE, RB_PIN_ETH_IE);         // 打开模拟外设功能，关闭数字功能

    // 初始化 ETH
    ch57x_eth_init(mac_addr, ETH_MAX_ETH_PAYLOAD);

    BSP_ETH_LED_GREEN_ON();

    // 启动接收，开启中断
    NVIC_SetPriority(ETH_IRQn, BSP_UART_ETH_PRI);
    NVIC_EnableIRQ(ETH_IRQn);

    return BSP_ETH_SUCCESS;
}


/**
  * @}
  */

/******************* (C)COPYRIGHT 2021 ***** END OF FILE *********************/
